package com.wing.res.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.chanjet.entity.material.MaterialCreateRequest;
import com.wing.chanjet.entity.material.MaterialRdrecordDetailsRequest;
import com.wing.chanjet.entity.others.OthersCreateRequest;
import com.wing.chanjet.entity.others.OthersRdrecordDetailsRequest;
import com.wing.chanjet.feign.ChanjetClient;
import com.wing.common.enums.MaintenanceEnum;
import com.wing.common.enums.ProductEnum;
import com.wing.common.exception.BusinessException;
import com.wing.common.utils.JsonResult;
import com.wing.platform.order.model.entity.Warehouse;
import com.wing.purchase.util.PurchaseSignUtil;
import com.wing.res.dao.ReceiptRecordDao;
import com.wing.res.model.entity.ReceiptRecord;
import com.wing.res.model.entity.ReceiptRecordDetail;
import com.wing.res.service.ReceiptRecordDetailService;
import com.wing.res.service.ReceiptRecordService;
import com.wing.sell.dao.DeliveryRecordDao;
import com.wing.sell.model.response.DeliveryRecordVO;
import com.wing.storage.dao.ProductStorageWorkOutDetailDao;
import com.wing.storage.model.entity.ProductStorageWorkOutDetail;
import com.wing.visual.dao.WarehouseDao;
import com.wing.web.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 领料记录-ServiceImpl
 *
 * @author xiayang
 */
@Service
@Slf4j
public class ReceiptRecordServiceImpl extends ServiceImpl<ReceiptRecordDao, ReceiptRecord> implements ReceiptRecordService {

    @Autowired
    ReceiptRecordDao receiptRecordDao;

    @Autowired
    private ReceiptRecordDetailService receiptRecordDetailService;

    @Autowired
    private DeliveryRecordDao deliveryRecordDao;

    @Autowired
    private ChanjetClient chanjetClient;

    @Autowired
    WarehouseDao warehouseDao;

    @Resource
    ProductStorageWorkOutDetailDao productStorageWorkOutDetailDao;

    @Override
    public Page<ReceiptRecord> list(Page page, Map<String, Object> params) {
        //领料记录详细列表
        Map<String, Object> detailParams = new HashMap<>();
        List<ReceiptRecordDetail> receiptRecordDetailList = receiptRecordDetailService.list(detailParams);
        //销售出库-交付记录列表
        List<DeliveryRecordVO> deliveryRecordList = deliveryRecordDao.list4app(null);
        //领料记录列表
        List<ReceiptRecord> list = baseMapper.list(page, params);
        for (ReceiptRecord receiptRecord : list) {
            List<ReceiptRecordDetail> detailList = receiptRecordDetailList.stream().
                    filter(t -> t.getReceiptRecordId().equals(receiptRecord.getId())).collect(Collectors.toList());
            receiptRecord.setReceiptNum(detailList.size());
            receiptRecord.setReceiptRecordDetailList(detailList);
            //销售出库
            if(StringUtils.isNotBlank(receiptRecord.getInventoryTypeCode()) && receiptRecord.getInventoryTypeCode().equals(PurchaseSignUtil.CPC)){
                //销售出库-交付记录
                DeliveryRecordVO sellDeliveryRecord = deliveryRecordList.stream().filter(t->t.getId().equals(receiptRecord.getWorkOrderId())).findFirst().orElse(null);
                receiptRecord.setWorkOrderCode(sellDeliveryRecord.getRecordCode());
                receiptRecord.setSellDeliveryRecord(sellDeliveryRecord);
            }
        }
        page.setRecords(list);
        return page;
    }

    @Override
    public void add(ReceiptRecord receiptRecord) {
        if (receiptRecord.getAuditPerson() == null) {
            throw new BusinessException("审核人不能为空");
        }
        //领取配料
        if (receiptRecord.getType().equals(ProductEnum.getTypeEmum.PL.getCode())) {
            receiptRecord.setCode("LL" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMAT));
            //待审核
            receiptRecord.setStatus(1);
            receiptRecord.setCreator(JwtUtils.getLoginUserId());
            receiptRecord.setCreatorName(JwtUtils.getLoginNickname());
            receiptRecord.setCreateTime(new Date());
            receiptRecord.setType(ProductEnum.getTypeEmum.PL.getCode());
            receiptRecord.setExternalCode(getCjtNumber());
            //新增领料记录
            this.baseMapper.insert(receiptRecord);
            //新增领料记录详细
            for (ReceiptRecordDetail receiptRecordDetail : receiptRecord.getReceiptRecordDetailList()) {
                receiptRecordDetail.setReceiptRecordId(receiptRecord.getId());
                receiptRecordDetail.setCreateTime(new Date());
            }
            receiptRecordDetailService.saveBatch(receiptRecord.getReceiptRecordDetailList());
        }else{
            receiptRecord.setCode("LL" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMAT));
            //待审核
            receiptRecord.setStatus(1);
            receiptRecord.setType(ProductEnum.getTypeEmum.SYD.getCode());
            receiptRecord.setCreator(JwtUtils.getLoginUserId());
            receiptRecord.setCreatorName(JwtUtils.getLoginNickname());
            receiptRecord.setCreateTime(new Date());
            receiptRecord.setExternalCode(getCjtNumber());
            //新增领料记录
            int insert = this.baseMapper.insert(receiptRecord);
            if (insert > 0) {
                //修改上一道工序的可领料数
                //查询上一道工序的信息
                Map<String,Object> map  = this.baseMapper.getUpWorkInfoBy(receiptRecord.getWorkOrderId());
                if (ObjectUtil.isNotEmpty(map)){
                    Long id = map.get("id")==null?0L:(Long)map.get("id");
                    int num = map.get("canGetQuantity")==null?0:(Integer)map.get("canGetQuantity");
                    num = num - receiptRecord.getGetQuantity();
                    baseMapper.updateWorkForCanGetQuaBy(id, num);
                }
            }
        }
        //领料出库-其他出库
        try{
            //otherOutProduct(receiptRecord);
        }catch (Exception e){
             log.info("领料出库-其他出库出现异常: " + e);
        }
   }

    @Override
    public void update(ReceiptRecord receiptRecord) {
        //更新领料记录
        receiptRecord.setAuditTime(new Date());
        this.baseMapper.updateById(receiptRecord);
//        //更新领料记录详细
//        for (ReceiptRecordDetail receiptRecordDetail : receiptRecord.getReceiptRecordDetailList()) {
//            receiptRecordDetail.setReceiptRecordId(receiptRecord.getId());
//        }
//        receiptRecordDetailService.saveOrUpdateBatch(receiptRecord.getReceiptRecordDetailList());
    }

    @Override
    public ReceiptRecord get(Map<String, Object> params) {
        ReceiptRecord receiptRecord = receiptRecordDao.get(params);
        if (ObjectUtil.isNotEmpty(receiptRecord)){
            receiptRecord.setWorkstationNatureName(MaintenanceEnum.workstationEmum.getNameByCode(receiptRecord.getWorkstationNature()));
        }
        if(receiptRecord!=null){
            //领料记录详细信息
            Map<String, Object> detailParam = new HashMap<>();
            detailParam.put("receiptRecordId", receiptRecord.getId());
            List<ReceiptRecordDetail> detailList = receiptRecordDetailService.list(detailParam);

            //查询历史已出库数量
            List<ProductStorageWorkOutDetail> productStorageWorkOutDetails2 = productStorageWorkOutDetailDao.selLeaveProductStorageNumList(Long.valueOf(params.get("id").toString()));

            //构建已出库数量的映射表
            Map<Long, BigDecimal> existedOutNumMap = new HashMap<>();
            for (ProductStorageWorkOutDetail detail : productStorageWorkOutDetails2) {
                existedOutNumMap.put(
                        detail.getProductDetailId(),
                        detail.getOutNum()
                );
            }

            for (ReceiptRecordDetail receiptRecordDetail : detailList) {
                BigDecimal existedOutNum = existedOutNumMap.getOrDefault(receiptRecordDetail.getProductDetailId(), BigDecimal.ZERO);
                receiptRecordDetail.setLeaveQuantity(existedOutNum);
            }

            receiptRecord.setReceiptRecordDetailList(detailList);
            return receiptRecord;
        }else{
            return null;
        }

    }

    /**
     * 审核
     * @param receiptId 领料id
     * @param status 状态
     * @return
     */
    @Override
    public boolean audit(String receiptId, String status) {
        ReceiptRecord byId = getById(receiptId);
        if (!byId.getStatus().equals(1)){
            return false;
        }
        if (ObjectUtil.isNotEmpty(byId)) {
            if ("2".equals(status)) {
                byId.setAuditTime(new Date());
                byId.setStatus(2);
                //1.修改表状态
                this.baseMapper.updateById(byId);
                //2.修改工单的领取个数
                Long workOrderId = byId.getWorkOrderId();
                return this.baseMapper.updateWorkInfoBy(workOrderId,byId.getGetQuantity());
            } else {
                //驳回
                byId.setStatus(4);
                int i = this.baseMapper.updateById(byId);
                return i > 0;
            }
        }
        return false;
    }



    /**
     * 其他出库
     */
    public void otherOutProduct(ReceiptRecord receiptRecord){
        try {
            OthersCreateRequest othersCreateRequest=new OthersCreateRequest();
            othersCreateRequest.setExternalCode(receiptRecord.getExternalCode());

            SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd");
            String workDate = simpleDateFormat2.format(new Date());
            othersCreateRequest.setVoucherDate(workDate);


            OthersCreateRequest.PurchaseBusiTypeRequest purchaseBusiTypeRequest=othersCreateRequest.new PurchaseBusiTypeRequest();
            purchaseBusiTypeRequest.setCode("13");
            othersCreateRequest.setBusiType(purchaseBusiTypeRequest);


            OthersCreateRequest.WarehouseRequest warehouseRequest= othersCreateRequest.new WarehouseRequest();
            Long warehouseId = receiptRecord.getReceiptWarehouse();
            if(warehouseId!=null){
                Warehouse warehouse = warehouseDao.selectById(warehouseId);
                if(warehouse!=null){
                    warehouseRequest.setCode(warehouse.getCode());
                    warehouseRequest.setName(warehouse.getName());
                }
            }
            othersCreateRequest.setWarehouse(warehouseRequest);
            othersCreateRequest.setMemo("外部接口-添加领料进入数据");


            List<OthersRdrecordDetailsRequest> rdrecordDetailsRequestList=new ArrayList<>();
            List<ReceiptRecordDetail> receiptRecordDetailList = receiptRecord.getReceiptRecordDetailList();
            for (ReceiptRecordDetail receiptRecordDetail : receiptRecordDetailList) {
                OthersRdrecordDetailsRequest rdrecordDetailsRequest=new OthersRdrecordDetailsRequest();
                OthersRdrecordDetailsRequest.InventoryRequest inventoryRequest= rdrecordDetailsRequest.new InventoryRequest();
                inventoryRequest.setCode(receiptRecordDetail.getSkuCode());

                rdrecordDetailsRequest.setInventory(inventoryRequest);
                rdrecordDetailsRequest.setQuantity(receiptRecordDetail.getReceiptNum());
                rdrecordDetailsRequestList.add(rdrecordDetailsRequest);
            }

            othersCreateRequest.setRDRecordDetails(rdrecordDetailsRequestList);
            JsonResult jsonResult = chanjetClient.syncOutSalesDispatch(othersCreateRequest);
            log.info(String.valueOf(jsonResult));
        }catch (Exception e){
            e.printStackTrace();
        }
    }



    /**
     * 材料出库
     * @param receiptRecord
     */
    public void materialOutInfo(ReceiptRecord receiptRecord){
        //领料出库-材料出库2
        try{
            MaterialCreateRequest materialCreateRequest=new MaterialCreateRequest();
            materialCreateRequest.setExternalCode(receiptRecord.getExternalCode());

            MaterialCreateRequest.PurchaseVoucherTypeRequest purchaseVoucherTypeRequest=materialCreateRequest.new PurchaseVoucherTypeRequest();
            purchaseVoucherTypeRequest.setCode("ST1022");

            materialCreateRequest.setVoucherType(purchaseVoucherTypeRequest);


            MaterialCreateRequest.PurchaseBusiTypeRequest purchaseBusiTypeRequest=materialCreateRequest.new PurchaseBusiTypeRequest();
            purchaseBusiTypeRequest.setCode("41");
            materialCreateRequest.setBusiType(purchaseBusiTypeRequest);

            SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd");
            String workDate = simpleDateFormat2.format(new Date());
            materialCreateRequest.setVoucherDate(workDate);


            MaterialCreateRequest.WarehouseRequest warehouseRequest= materialCreateRequest.new WarehouseRequest();
            Long warehouseId = receiptRecord.getReceiptWarehouse();
            if(warehouseId!=null){
                Warehouse warehouse = warehouseDao.selectById(warehouseId);
                if(warehouse!=null){
                    warehouseRequest.setCode(warehouse.getCode());
                    warehouseRequest.setName(warehouse.getName());
                }
            }

            materialCreateRequest.setWarehouse(warehouseRequest);

            materialCreateRequest.setMemo("外部接口-添加领料进入数据");

            List<MaterialRdrecordDetailsRequest> rdrecordDetailsRequestList=new ArrayList<>();


            List<ReceiptRecordDetail> receiptRecordDetailList = receiptRecord.getReceiptRecordDetailList();
            for (ReceiptRecordDetail receiptRecordDetail : receiptRecordDetailList) {
                MaterialRdrecordDetailsRequest rdrecordDetailsRequest=new MaterialRdrecordDetailsRequest();

                MaterialRdrecordDetailsRequest.InventoryRequest inventoryRequest= rdrecordDetailsRequest.new InventoryRequest();
                inventoryRequest.setCode(receiptRecordDetail.getSkuCode());
                inventoryRequest.setName(receiptRecordDetail.getSkuName());

                rdrecordDetailsRequest.setInventory(inventoryRequest);
                rdrecordDetailsRequest.setBaseQuantity(receiptRecordDetail.getReceiptNum());

                rdrecordDetailsRequestList.add(rdrecordDetailsRequest);

            }
            materialCreateRequest.setRDRecordDetails(rdrecordDetailsRequestList);

            JsonResult jsonResult = chanjetClient.syncAddMaterialDispatch(materialCreateRequest);
            log.info(String.valueOf(jsonResult));

        }catch (Exception e){
            //e.printStackTrace();
            log.info("领料出库-材料出库异常："+e);
        }

    }



    public String getCjtNumber(){
        // 获取当前日期和时间
        LocalDateTime now = LocalDateTime.now();

        // 定义日期时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

        // 格式化当前日期和时间
        String formattedDateTime = now.format(formatter);

        // 生成最终字符串
        String result = "MTCJT" + formattedDateTime;

        return result;
    }
}
